package com.monolithiot.camera.service;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.monolithiot.camera.GeneralResult;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class ProtonServer {

    final SocketServer socketServer;

    public ProtonServer(SocketServer socketServer) {
        this.socketServer = socketServer;
    }

    /**
     * 服务器
     *
     * @param port 端口
     * @throws Exception error
     */
    public void server(int port) throws Exception {
        System.out.println("ProtonServer started!");
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(port));
        serverSocketChannel.configureBlocking(false);
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        // 用于存储未完整接收的数据片段
        StringBuilder partialData = new StringBuilder();
        while (true) {
            if (selector.select() > 0) {
                Set<SelectionKey> selectedKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectedKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    // 处理新接入的请求
                    if (key.isAcceptable()) {
                        ServerSocketChannel serverSocketChannelNew = (ServerSocketChannel) key.channel();
                        SocketChannel socketChannel = serverSocketChannelNew.accept();
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector, SelectionKey.OP_READ);
                    }
                    // 处理读取的请求
                    if (key.isReadable()) {
                        SocketChannel channel = (SocketChannel) key.channel();
                        buffer.clear();
                        try {
                            int numRead = channel.read(buffer);
                            if (numRead == -1) {
                                channel.close();
                                key.cancel();
                                continue;
                            }
                        } catch (IOException e) {
                            System.out.println("Error reading data from client: " + e.getMessage());
                            continue;
                        }
                        buffer.flip();
                        while (buffer.hasRemaining()) {
                            char c = (char) buffer.get();
                            if (c == '\u0002') { // 开始标志
                                partialData.setLength(0); // 清空之前的数据
                            } else if (c == '\u0003') { // 结束标志
                                String receivedData = partialData.toString();
                                if (!receivedData.isEmpty()) {
                                    JSONObject entries;
                                    // 处理接收到的数据
                                    try {
                                        entries = JSONUtil.parseObj(receivedData);
                                    } catch (Exception e) {
                                        System.out.println("error data: " + e.getMessage());
                                        System.out.println(receivedData);
                                        continue;
                                    }
                                    if (entries.get("reason").equals("event_arq")) {
                                        System.out.println("error data: " + receivedData);
                                        continue;
                                    } else {
                                        // 响应客户端
                                        ByteBuffer responseBuffer = ByteBuffer.allocate(1024);
                                        Map<String, Object> payload = new HashMap<>();
                                        payload.put("type", "response");
                                        responseBuffer.put(JSONUtil.toJsonStr(GeneralResult.ok(payload)).getBytes());
                                        responseBuffer.flip();
                                        if (channel.isOpen()) {
                                            channel.write(responseBuffer);
                                        } else {
                                            System.out.println("Client connection closed. Unable to write response.");
                                            break;
                                        }
                                        // 发送数据到 WebSocket 客户端
                                        socketServer.broadcast(JSONUtil.toJsonStr(GeneralResult.ok(JSONUtil.parseObj(receivedData))));
                                    }
                                }
                                System.out.println("Received data: " + receivedData);

                            } else {
                                partialData.append(c); // 将字符添加至未完整数据片段中
                            }
                        }
                    }
                    iterator.remove();
                }
            }
        }
    }


}
